<?php

    if (!defined('__IS_LEAF__')) exit('Access Denied!');
    
    /**
     * MysqlPDO驱动类
     * 如果错误模式选择的异常模式，则数据库执行有误就会中断
     */
    class MysqlPDO{

        private $_dsn;                           //dsn源
        private $_tableName;                     //操作的表
        private $_lastSql;                       //最后一条执行的sql
        static private $_pdo;                    //pdo对象

        /**
         * 初始化MysqlPDO驱动类，该类通用，并非只适用于MySQL
         * @access public
         * @param array $config 连接数据库相关的配置信息
         */
        public function __construct($configArr){
            //检查系统是否开启了PDO拓展
            if(!extension_loaded('pdo_mysql'))  $this->error(L('extension').'pdo_mysql'.L('is_not_open'));
            //初始化dsn及pdo调优参数
            $this->_initDsnDbops($configArr);
            //执行数据库连接
            $this->_connect();
        }

        /**
         * 初始化dns属性
         * @access public
         * @param array $config 连接数据库相关的配置信息
         */
        private function _initDsnDbops($configArr){
            //获取数据库类型
            $this->_dbType          = C('db_type');
            //将数据库一些内容定义为常量，防止dao直接被打印看到数据库信息
            define('__DB_HOST__', $configArr[0]);
            define('__DB_PORT__', $configArr[1]);
            define('__DB_NAME__', $configArr[2]);
            define('__DB_USER__', $configArr[3]);
            define('__DB_PWD__',  $configArr[4]);
            $this->_tableName    = $configArr[5];
            //不同数据库的dsn格式不同，此处为多类型数据库提供可选项
            switch ($this->_dbType) {
                case 'mysql':
                    //拼装dsn
                    $this->_dsn = $this->_dbType.':host='.__DB_HOST__.';dbname='.__DB_NAME__.';port='.__DB_PORT__;
                    break;
                default:
                    # code...
                    break;
            }
        }

        private function _connect(){
            //如果已经存在连接，则不需另行创建
            if(self::$_pdo) return $this->_pdo;
            //调优PDO
            $dbOps = array(
                    PDO::ATTR_PERSISTENT=>C('db_persistent'),               //是否持久化连接
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',   //设置字符集
                    PDO::ATTR_ERRMODE=>2,                                   //设置错误处理模式为异常
                    PDO::ATTR_AUTOCOMMIT=>0,                                //关闭自动提交,对PDO处理事务有效
            );
            try{
                //实例化PDO类
                switch ($this->_dbType) {
                    case 'mysql':
                        self::$_pdo = new PDO($this->_dsn, __DB_USER__, __DB_PWD__, $dbOps);
                        break;
                    default:
                        # code...
                        break;
                }
            }catch(PDOException $e){
                //此处的错误可能性有两个，一个是无法连接数据库，一个是数据库可以连接，但是表不存在
                (self::$_pdo===null) ? $this->error(L('db_not_connected')) : $this->error(L('pdo_connect_error').'：'.$e->getMessage());
            }
        }

        public function insert(){

        }

        public function delete(){

        }

        public function update(){

        }

        /**
         * 获取结果集
         * @param string $sql 要查询的$sql语句，此语句为预处理sql
         * @param array $data 预处理时，绑定的参数
         */
        public function select($table, $fields, $where, $group, $order, $limit, $values){
            echo '<br>'.$sql = 'SELECT '.$fields.' FROM '.$table.' '.$where.' '.$group.' '.$order.' '.$limit;
            $stmt = $this->_fetchPrepare($sql, $values);
            $res  = $stmt->fetchAll();
            //如果开启了数据库信息统计模式，则执行统计方法
            if(__DB_STATS__){

            }
            return $res;
        }

        /**
         * 获取最近一次的数据库操作信息，如查询时间、sql内容
         */
        public function getLastQueryInfo(){

        }

        /**
         * 执行有结果集的查询
         */
        public function query($sql){
            $stmt = $this->_fetchPrepare($sql);
            return $stmt->fetchAll();
        }

        /**
         * 执行有返回修改主键的查询，如增、删、改
         */
        public function exec($sql){
            $res = $this->_pdo->exec($sql);
            return $res==true ? true : false;
        }

        /**
         * 使用预处理，获取执行sql语句的预处理对象
         */
        private function _fetchPrepare($sql,$data){
            try{
                $this->_setLastSql($sql);
                $stmt = self::$_pdo->prepare($sql);
                $stmt->setFetchMode(PDO::FETCH_ASSOC);
                $stmt->execute($data);
                return $stmt;                
            }catch(PDOException $e){
                $this->error(L('pdo_query_error').'：'.$sql);
            }
        }

        /**
         * getPrepareData 获取用于预处理的data数组
         */
        private function _getPrepareData($data){

        }

        final private function error($msg){
            error($msg);
        }

        private function _setLastSql($sql){
            $this->_lastSql = $sql;
        }

        public function getLastSql(){
            return $this->_lastSql;
        }

        public function __destruct(){
            unset($this->_pdo);
        }
    }